import {
  ParsedTransactionWithMeta,
  ParsedInstruction,
  PartiallyDecodedInstruction,
  PublicKey,
} from '@solana/web3.js';
import {
  View,
  Text,
  GestureResponderEvent,
  Linking,
  TouchableOpacity,
} from 'react-native';
import tw from 'twrnc';

import {primaryColor2, primaryColor3} from '../../../../theme/default';
import {useCallback, useEffect, useState} from 'react';
import {
  formatNumber,
  formatTimestamp,
  parseSolanaScanTxUrl,
  parseValue,
  toShortAddress,
} from '../../../../utils';
import {UserToken} from '../../../../db/models/userTokenModel';
import {useAccountProvider} from '../../../../hooks/useAccountProvider';
import {useTranslation} from 'react-i18next';
import {getAccount, getAssociatedTokenAddress} from '@solana/spl-token';
import {useSolanaClientProvider} from '../../../../hooks/useSolana/useSolanaClientProvider';

type TokenTxHistoryItemProp = {
  isNative: boolean;
  tokenInfo: UserToken;
  txHistory?: ParsedTransactionWithMeta;
  parsedTx?: ParsedInstruction | PartiallyDecodedInstruction;
  onPress?: (event: GestureResponderEvent) => void;
};

export default function TokenTxHistoryItem({
  tokenInfo,
  isNative,
  txHistory,
  parsedTx,
  onPress,
}: Readonly<TokenTxHistoryItemProp>) {
  const {solanaClient} = useSolanaClientProvider();
  const [fromAddress, setFromAddress] = useState<string>();
  const [toAddress, setToAddress] = useState<string>();
  const [amount, setAmount] = useState<string>();
  const [signature, setSignature] = useState<string>();
  const [historyType, setHistoryType] = useState<string>();
  const {t} = useTranslation();
  const {userInfo} = useAccountProvider();
  const parseHistoryData = async () => {
    const parsed = (parsedTx! as ParsedInstruction).parsed;
    const _signature = (txHistory as ParsedTransactionWithMeta).transaction
      .signatures[0];
    setSignature(_signature);
    const info = parsed['info'];
    let _fromAddress;
    let _toAddress;
    let _historyType;
    let _amount;
    if (isNative) {
      //SOL
      _fromAddress = info['source'];
      _toAddress = info['destination'];
      _amount = formatNumber(
        parseValue(info['lamports'], tokenInfo.decimals),
        2,
        6,
      );

      if (_fromAddress.toLowerCase() == userInfo?.solanaAddress.toLowerCase()) {
        _historyType = 'Send';
      } else {
        _historyType = 'Receive';
      }
    } else {
      //SPL
      const fromAssociatedTokenAddress = await getAssociatedTokenAddress(
        new PublicKey(tokenInfo.address),
        new PublicKey(userInfo!.solanaAddress),
      );
      if (
        info['source'].toLowerCase() ==
        fromAssociatedTokenAddress.toBase58().toLocaleLowerCase()
      ) {
        _historyType = 'Send';
        _fromAddress = userInfo?.solanaAddress;
        const account = await getAccount(
          solanaClient!,
          new PublicKey(info['destination']),
        );
        _toAddress = account.owner.toBase58();
      } else {
        _historyType = 'Receive';

        const account = await getAccount(
          solanaClient!,
          new PublicKey(info['source']),
        );
        _fromAddress = account.owner.toBase58();
        _toAddress = userInfo?.solanaAddress;
      }

      _amount = formatNumber(info['tokenAmount']['uiAmount'], 2, 6);
    }

    setFromAddress(_fromAddress);
    setToAddress(_toAddress);
    setAmount(_amount);
    setHistoryType(_historyType);
  };

  const handleOpenSolanaScan = useCallback(async () => {
    if (signature !== undefined) {
      const url = parseSolanaScanTxUrl(signature);

      const supported = await Linking.canOpenURL(url);
      if (supported) {
        await Linking.openURL(url);
      }
    }
  }, [signature]);

  useEffect(() => {
    parseHistoryData();
  }, [tokenInfo, isNative, txHistory, parsedTx, userInfo, solanaClient]);

  return (
    <TouchableOpacity
      onPress={handleOpenSolanaScan}
      style={{paddingVertical: 0}}>
      <View
        style={{
          ...tw.style('flex flex-row items-center justify-between'),
          height: 56,
        }}>
        <View
          style={{
            ...tw.style('flex flex-col gap-1'),
            height: '100%',
            justifyContent: 'center',
          }}>
          <Text style={tw.style(`text-[${primaryColor2}] text-[12px]`)}>
            {t(historyType!)}
          </Text>
          <Text style={tw.style(`text-[${primaryColor3}] text-[12px]`)}>
            {undefined == historyType
              ? '--'
              : 'Receive' == historyType
              ? `${t('from')} ${toShortAddress(fromAddress!, 8)}`
              : `${t('to')} ${toShortAddress(toAddress!, 8)}`}
          </Text>
        </View>

        <View
          style={{
            ...tw.style('flex flex-col gap-1'),
            height: '100%',
            justifyContent: 'center',
          }}>
          <Text
            style={tw.style(`text-[${primaryColor2}] text-[14px] text-right`)}>
            {`${
              undefined == historyType
                ? ''
                : 'Receive' == historyType
                ? '+'
                : '-'
            }${amount}`}
          </Text>
          <Text
            style={tw.style(`text-[${primaryColor3}] text-[12px] text-right`)}>
            {formatTimestamp(Number(txHistory?.blockTime) * 1000)}
          </Text>
        </View>
      </View>
    </TouchableOpacity>
  );
}
